agentmux_srv\backend\history/
adapter.rs

1// Copyright 2026, AgentMux Corp.
2// SPDX-License-Identifier: Apache-2.0
3
4//! History adapter trait and shared types.
5
6use serde::{Deserialize, Serialize};
7
8/// Error type for history operations.
9#[derive(Debug)]
10pub enum HistoryError {
11    Io(std::io::Error),
12    Json(serde_json::Error),
13    Other(String),
14}
15
16impl std::fmt::Display for HistoryError {
17    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18        match self {
19            HistoryError::Io(e) => write!(f, "IO error: {}", e),
20            HistoryError::Json(e) => write!(f, "JSON error: {}", e),
21            HistoryError::Other(s) => write!(f, "{}", s),
22        }
23    }
24}
25
26impl From<std::io::Error> for HistoryError {
27    fn from(e: std::io::Error) -> Self {
28        HistoryError::Io(e)
29    }
30}
31
32impl From<serde_json::Error> for HistoryError {
33    fn from(e: serde_json::Error) -> Self {
34        HistoryError::Json(e)
35    }
36}
37
38/// A discovered file on disk (path + modification time).
39pub struct DiscoveredFile {
40    pub file_path: String,
41    pub mtime_ms: i64,
42}
43
44/// Lightweight metadata for the session list — extracted without full parsing.
45#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct SessionMeta {
47    pub session_id: String,
48    pub file_path: String,
49    pub provider: String,
50    pub model: String,
51    pub slug: String,
52    pub working_directory: String,
53    pub created_at: i64,
54    pub modified_at: i64,
55    pub message_count: u32,
56    pub first_user_message: String,
57    pub file_size_bytes: u64,
58    pub git_branch: String,
59    pub total_tokens: u64,
60    pub subagent_count: u32,
61}
62
63/// Full parsed session — produced on demand when user opens a conversation.
64#[derive(Debug, Clone, Serialize, Deserialize)]
65pub struct HistorySession {
66    pub meta: SessionMeta,
67    pub messages: Vec<HistoryMessage>,
68}
69
70/// A single message in a conversation.
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct HistoryMessage {
73    pub role: String,
74    pub content: String,
75    pub timestamp: i64,
76    pub tool_uses: Vec<ToolUseSummary>,
77}
78
79/// Summary of a tool call within an assistant message.
80#[derive(Debug, Clone, Serialize, Deserialize)]
81pub struct ToolUseSummary {
82    pub name: String,
83    pub argument_summary: String,
84}
85
86/// One implementation per CLI provider.
87pub trait HistoryAdapter: Send + Sync {
88    /// Provider identifier (e.g., "claude", "codex", "gemini", "kimi", "openclaw", "pi").
89    fn provider(&self) -> &str;
90
91    /// Discover all session file paths on disk.
92    /// Returns (file_path, mtime_ms) pairs, sorted by mtime descending.
93    fn discover_files(&self) -> Result<Vec<DiscoveredFile>, HistoryError>;
94
95    /// Extract lightweight metadata without full parsing.
96    fn extract_meta(&self, file_path: &str) -> Result<Option<SessionMeta>, HistoryError>;
97
98    /// Parse a single session file into a full HistorySession.
99    fn parse_file(&self, file_path: &str) -> Result<Option<HistorySession>, HistoryError>;
100}